float colormap_h(float x) {
	if (x < 0.1167535483837128) {
		return 2.0 / 3.0; // H1
	} else if (x < 0.1767823398113251) {
		return ((-3.19659402385354E+02 * x + 1.14469539590179E+02) * x - 1.52210982227697E+01) * x + 1.39214703883044E+00; // H2
	} else if (x < 0.2266354262828827) {
		return ((-3.55166097640991E+02 * x + 2.51218596935272E+02) * x - 6.08853752315044E+01) * x + 5.38727123476564E+00; // H3
	} else if (x < (6.95053970124612E-01 - 4.13725796136428E-01) / (1.48914458632691E+00 - 6.97458630656247E-01)) {
		return -1.48914458632691E+00 * x + 6.95053970124612E-01; // H4
	} else if (x < (4.13725796136428E-01 - 2.48329223043123E-01) / (6.97458630656247E-01 - 3.48617475202321E-01)) {
		return -6.97458630656247E-01 * x + 4.13725796136428E-01; // H5
	} else {
		return -3.48617475202321E-01 * x + 2.48329223043123E-01; // H6
	}
}

float colormap_v(float x) {
	float v = 1.0;
	if (x < 0.115834504365921) {
		v = 4.18575376272140E+00 * x + 5.15145240089963E-01; // V1-Hi
	} else if (x < (1.90980360972022E+00 + 9.13724751363001E-01) / (7.87450639585523E+00 + 7.87450803534638E+00)) {
		v = -7.87450803534638E+00 * x + 1.90980360972022E+00; // V2-Hi
	} else if (x < 0.5) {
		v = 7.87450639585523E+00 * x - 9.13724751363001E-01; // V3-Hi
	} else {
		v = -1.87540494049556E+00 * x + 2.33603077812338E+00; // V4-Hi
	}
	v = clamp(v, 0.0, 1.0);

	float period = 4.0 / 105.0;
	float len = 3.0 / 252.0;
	float t = mod(x + 7.0 / 252.0, period);
	if (0.0 <= t && t < len) {
		if (x < 0.115834504365921) {
			v = 3.74113124408467E+00 * x + 4.64654322955584E-01; // V1-Lo
		} else if (x < (1.90980360972022E+00 + 9.13724751363001E-01) / (7.87450639585523E+00 + 7.87450803534638E+00)) {
			v = -3.97326878048783E+00 * x + 1.25308500609757E+00; // V2-Lo
		} else if (x < 0.25) {
			v = 6.99297032967038E+00 * x - 8.03946549450558E-01; // V3-Lo
		} else if (x < 0.72) {
			v -= 26.0 / 255.0;
		} else {
			v = -1.67870020621040E+00 * x + 2.09414636280895E+00; // V4-Lo
		}
	}

	return v;
}

// H1 - H2 = 0
// => [x=0.1167535483837128]

// H2 - H3 = 0
// => [x=0.1767823398113251,x=0.1822494566440582,x=3.492328017950058]

// H3 - H4 = 0
// => [x=0.2266354262828827]

// V1-Hi - 1 = 0
// => [x=0.115834504365921]

// V2-Hi - V3-Hi = 0
// => 

vec4 colormap_hsv2rgb(float h, float s, float v) {
	float r = v;
	float g = v;
	float b = v;
	if (s > 0.0) {
		h *= 6.0;
		int i = int(h);
		float f = h - float(i);
		if (i == 1) {
            r *= 1.0 - s * f;
            b *= 1.0 - s;
		} else if (i == 2) {
			r *= 1.0 - s;
			b *= 1.0 - s * (1.0 - f);
		} else if (i == 3) {
			r *= 1.0 - s;
			g *= 1.0 - s * f;
		} else if (i == 4) {
			r *= 1.0 - s * (1.0 - f);
			g *= 1.0 - s;
		} else if (i == 5) {
			g *= 1.0 - s;
			b *= 1.0 - s * f;
		} else {
			g *= 1.0 - s * (1.0 - f);
			b *= 1.0 - s;
		}
	}
	return vec4(r, g, b, 1.0);
}

vec4 colormap(float x) {
	float h = colormap_h(clamp(x, 0.0, 1.0));
	float s = 1.0;
	float v = colormap_v(clamp(x, 0.0, 1.0));
	return colormap_hsv2rgb(h, s, v);
}
